package com.karolak.sm;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.karolak.sm.context.StateConfig;
import com.karolak.sm.event.Event;
import com.karolak.sm.exception.TransitionException;
import com.karolak.sm.state.State;
import com.karolak.sm.state.StateId;
import com.karolak.sm.state.Transition;

public class StateMachineImpl {

	protected Log log = LogFactory.getLog(getClass());

	private StateConfig config;

	private State state;

	public StateMachineImpl() {
		config = new StateConfig();
	}

	// === init api === //
	public void registerStates(List<State> states) {
		getConfig().registerStates(states);
	}

	public void registerTransitions(List<Transition> transitions) {
		getConfig().registerTransitions(transitions);
	}

	// === sm api === //
	public Transition getTransition(Event event) {
		return getConfig().getTransition(event);
	}

	// === event handling api ===//
	public void update(Event event) {
		// TODO Auto-generated method stub
		Transition transition = getConfig().getTransition(event);
		if (transition == null) {
			// log
			return;
		}
		StateId stateId = transition.getTargetStateId();
		if (stateId == null) {
			// log
			return;
		}
		State state = getConfig().getState(stateId);
		if (state == null) {
			// log
			return;
		}
		setState(state);
	}

	// === api === //
	public StateId getStateId() {
		return getState().getStateId();
	}

	// === transition api === //

	// === utility api === //
	protected void handleException(Exception e) {
		if (e instanceof TransitionException) {
			log.warn(e.getMessage());
		} else {
			log.error("Unhandled exception:", e);
		}
	}

	// === get/set === //
	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	protected StateConfig getConfig() {
		return config;
	}

	protected void setConfig(StateConfig config) {
		this.config = config;
	}
}
